package ${filePackageName};

import cn.hutool.core.util.StrUtil;
import ${annotationPackage}.SubmitValid;
import ${enumsPackage}.EnumCode;
import ${exceptionPackage}.BusinessException;
import ${redisPackage}.RedisUtils;
import ${utilsPackage}.ConstantUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

/**
 * 请求切面类
 * @author ${projectAuthor}
 * @version 1.0
 * @date ${nowDate}
 */
@Aspect
@Component
public class SubmitAspect {

	@Resource
	private RedisUtils redisUtils;

	private Logger logger = LoggerFactory.getLogger(SubmitAspect.class);

	@Around(value = "@annotation(submitValid)")
	public Object logAround(ProceedingJoinPoint joinPoint, SubmitValid submitValid) throws Throwable {

		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
		String token = request.getHeader(ConstantUtil.DEFAULT_AUTH_TOKEN);
		if (StrUtil.isBlank(token)) {
			token = request.getParameter(ConstantUtil.DEFAULT_AUTH_TOKEN);
		}
		if (StrUtil.isNotBlank(token)) {
			token = token.replaceAll("%2B", "+").replaceAll(" ", "+");
		}
		String redisKey = token + request.getMethod()+request.getRequestURI();
		if(redisUtils.hasKey(redisKey)){
			throw new BusinessException(EnumCode.REQUEST_FREQUENT,"请求过于频繁，请稍后再试！");
		}
		redisUtils.set(redisKey, System.currentTimeMillis(),10*60);
		// 执行方法体
		Object result = joinPoint.proceed();
		redisUtils.del(redisKey);
		return result;
	}

	@AfterThrowing(value = "@annotation(submitValid)", throwing = "e")
	public void afterThrowing(JoinPoint joinPoint, SubmitValid submitValid, Throwable e) throws Throwable {
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
		String token = request.getHeader(ConstantUtil.DEFAULT_AUTH_TOKEN);
		if (StrUtil.isBlank(token)) {
			token = request.getParameter(ConstantUtil.DEFAULT_AUTH_TOKEN);
		}
		if (StrUtil.isNotBlank(token)) {
			token = token.replaceAll("%2B", "+").replaceAll(" ", "+");
		}
		String redisKey = token + request.getMethod()+request.getRequestURI();
		redisUtils.del(redisKey);
	}

}
